package uk.co.hephistocles.blobGame;

import java.io.PrintWriter;
import java.util.LinkedList;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.actions.FadeTo;
import com.badlogic.gdx.scenes.scene2d.actions.MoveTo;
import com.badlogic.gdx.scenes.scene2d.actions.Parallel;
import com.badlogic.gdx.scenes.scene2d.actors.Image;
import com.badlogic.gdx.scenes.scene2d.actors.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Button;
import com.badlogic.gdx.scenes.scene2d.ui.Button.ClickListener;

public class LevelMenu extends Dialog{
	private LinkedList<Integer>	lx;
	private LinkedList<Integer>	ly;
	private static boolean exiting;
	private static boolean entering;
	private float swipeTime;
	private final float swipeTotal = 0.3f;
	public int world;
	public Button[] button;
	public Image[] crosses;
	public Image[][] stars;
	public Label title;
	
	private boolean swipeFromRight;

	public LevelMenu() {
		menu = new Stage(Gdx.graphics.getWidth(),Gdx.graphics.getHeight(),true);
		menu.getRoot().x =0;//-Gdx.graphics.getWidth();
		menu.getRoot().y =0;
		
		lx = new LinkedList<Integer>();
		ly = new LinkedList<Integer>();
		button = new Button[15];
		crosses = new Image[15];
		stars = new Image[15][4];
	}
	
	@Override
	public void clear() {
		menu.clear();
		exiting = false;
		lx.clear();
		ly.clear();
		int btnHeight = 70;
		int btnWidth = 70;
		int titleHeight = 50;
		int height = (Gdx.graphics.getHeight()-titleHeight)/3;
		int width = Gdx.graphics.getWidth()/5;
		addImage(Game.menuBg);
		for (int i=0; i<15; i++) {
			//draw bg
			//create the title label
			title = addLabel("levelTitle","", Game.fontL, Color.WHITE);
			title.x = (Gdx.graphics.getWidth() - title.width)/2;;
			title.y = (Gdx.graphics.getHeight()-50+title.height/2);
			title.visible = true;
			//create dummy buttons
			button[i] = addButton("levelBtn" + i, ""+(i+1), Game.btnFont,
					Game.dwnBtn, Game.upBtn, null);
			button[i].touchable = false;
			//move buttons to the right place
			button[i].x = width/2 - btnWidth/2 +  (i%5)*width;
			button[i].y = Gdx.graphics.getHeight() -(titleHeight+height/2 + btnHeight/2 + ((i-i%5)/5)*height);
			button[i].height = btnHeight;
			button[i].width = btnWidth;
			
			//create dummy crosses in the right places
			crosses[i] = addImage("btnCross" + i, Game.btnCross,width/2 - Game.btnCross.getWidth()/2 +  (i%5)*width,
					Gdx.graphics.getHeight() -(titleHeight+height/2 + Game.btnCross.getHeight()/2 + ((i-i%5)/5)*height));
			crosses[i].visible = false;
			
			//create dummy stars in the right places
			for (int j=0; j<3; j++) {
				stars[i][j] = addImage("star" + i + ":" + j, Game.stars[j],(i%5)*width + j*width/3,
						Gdx.graphics.getHeight() -(titleHeight+height/2 - (j%2)*Game.stars[j].getRegionHeight()/2 + ((i-i%5)/5)*height));
				stars[i][j].visible = false;
			}
			stars[i][3] = addImage("star" + i + ":3", Game.stars[3],(i%5)*width + width/2 - Game.stars[3].getRegionWidth()/2,
					Gdx.graphics.getHeight() -(titleHeight+3*height/4 + Game.stars[3].getRegionHeight()/2 + ((i-i%5)/5)*height));
			stars[i][3].visible = false;
		}
	}
	
	public void prepareWorld(int world) {
		this.world = world;
		final int worldID = Integer.parseInt(Game.EXTERNAL.child("auth").readString().split(",")[2*(world-1)]);
		System.out.println("Preparing world " + world + " with ID " + worldID);
		//Update level locks
		FileHandle handle = Game.EXTERNAL.child(worldID+"/scores.txt");
		
		if (!handle.exists()) {
			PrintWriter levelTxt = new PrintWriter(handle.write(false));
			
			levelTxt.print("1,0,0,0,0,0;");
			for (int i=1; i<15; i++) {
				levelTxt.print("0,0,0,0,0,0;");
			}
			levelTxt.close();
		}
		String[] levels = handle.readString().split(";");
		//set title
		title.setText(Game.EXTERNAL.child("auth").readString().split(",")[2*(world-1)+1]);
		title.x = (Gdx.graphics.getWidth() - title.width)/2;
		title.y = (Gdx.graphics.getHeight()-50+title.height/2);
		for (int i=0; i<15; i++) {
			String [] levelData = levels[i].split(",");
			final int levelNum = i+1;
			//if the level is not unlocked
			if (Float.parseFloat(levelData[0])!=1) {
				//draw a cross
				crosses[i].visible = true;
				button[i].setClickListener(null);
				button[i].touchable = false;
			} else {
				//if the level is unlocked, do not draw a cross
				crosses[i].visible = false;
				//but add a click listener to the button
				button[i].setClickListener(new ClickListener() {
						@Override
						public void click(Button btn) {
							if (!LevelMenu.entering && !LevelMenu.exiting) {
								menu.clear();
								Game.ACTIVEWORLD = worldID;
								Game.level.initLevel(worldID, levelNum);
								Game.startTrace();
							}
						}
					});
				button[i].touchable = true;
			}
			for (int j=0; j<3; j++) {
				//draw stars as appropriate
				if (Float.parseFloat(levelData[j+1])==1) {
					stars[i][j].visible = true;
				} else {
					stars[i][j].visible = false;
				}
			}
			//draw the perfect if necessary
			if (Float.parseFloat(levelData[4])==1) {
				stars[i][3].visible = true;
			} else {
				stars[i][3].visible = false;
			}
		}
		entering = false;
		exiting = false;
    	menu.getRoot().x=0;
    	menu.getRoot().y=0;
    	menu.getRoot().color.a = 1;
	}
	
	@Override
	public void update(float dt) {
		if (exiting) {
			if ((swipeTime<=0)) {
				exiting = false;
				if (world > Game.TOTWORLDS) {
					world=1;
				} else if (world<1) {
					world = Game.TOTWORLDS;
				}
				prepareWorld(world);
				enter(swipeFromRight);
			} else {
				swipeTime -=dt;
			}
		} else if (entering) {
				if ((swipeTime<=0)) {
					entering = false;
				} else {
					swipeTime -=dt;
				}
			}
		menu.act(dt);
	}
	


    @Override public boolean touchUp (int x, int y, int pointer, int button) {
        menu.touchUp(x, y, pointer, button);
        lx.clear();
        ly.clear();
        return false;
    }

    public void exit(boolean right) {
    	exiting = true;
    	world += right?-1:1;
    	menu.getRoot().x=0;
    	menu.getRoot().y=0;
    	menu.getRoot().color.a = 1;
    	menu.getRoot().action(Parallel.$(MoveTo.$((float) ((right?0.5:-0.5)*Gdx.graphics.getWidth()),0,swipeTotal),
    			FadeTo.$(0, swipeTotal)));
    	swipeTime = swipeTotal;
    	swipeFromRight = !right;
    }
    public void enter(boolean fromRight) {
    	entering = true;
    	menu.getRoot().x=(float) ((fromRight?0.5:-0.5)*Gdx.graphics.getWidth());
    	menu.getRoot().y=0;
    	menu.getRoot().color.a = 0;
    	menu.getRoot().action(Parallel.$(MoveTo.$(0,0,swipeTotal),
    			FadeTo.$(1, swipeTotal)));
    	swipeTime = swipeTotal;
    }
    @Override
    public boolean touchDragged (int x, int y, int pointer) {     
        menu.touchDragged(x, y, pointer);
        
        if ((!entering) && (!exiting)) {
            //Swipe Detection
            int thresh = 50;
            lx.add(x);
            ly.add(y);
            if (lx.size() > 5) {
            	lx.removeFirst();
            	ly.removeFirst();
            }
            
            if (lx.getFirst() - lx.getLast()>thresh) {
            	exit(false);
            } else if (lx.getFirst() - lx.getLast()< -thresh) {
            	exit(true);
            }
	    }
        return false;
    }
}